package org.example.network;

import java.io.DataInputStream;
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * 飞书服务端: 连接客户端, 转发客户端消息(群发,私发)
 *  作业:
 *      1. 实现文件的群发和私发
 *      2. 如何文件大小超过 1MB, 则对文件进行压缩后发送
 *         接收端: 根据发送的参数, 则解压缩, 还原文件
 */
public class FlyBookServer {

    public static void main(String[] args) throws IOException {
        FlyBookServer flyBookServer = new FlyBookServer();
        flyBookServer.start();
    }

    Map<String,Socket> socketMap = new HashMap<String,Socket>();

    public void start() throws IOException{
        ServerSocket serverSocket = new ServerSocket(8888);
        Socket socket;
        while((socket = serverSocket.accept()) != null) {
            // 每个客户端连接, 接收到的第一个消息就是该用的姓名(唯一表示)
            DataInputStream dataInputStream =
                    new DataInputStream(socket.getInputStream());
            String name = dataInputStream.readUTF();
            socketMap.put(name, socket);
            System.out.println("客户端" + name + "连接成功");

            new Thread(()->transfar(name)).start();
        }
    }

    // 转发消息
    public void transfar(String name){
        Socket socket = socketMap.get(name);
        try {
            DataInputStream dataInputStream =
                    new DataInputStream(socket.getInputStream());
            while (true) {
                String type = dataInputStream.readUTF();
                if(type.startsWith("msg")){
                    Collection<Socket> recvs;
                    if(type.equals("msg")){
                        // 群发
                        recvs = socketMap.values();
                    } else {
                        // 私发
                        String[] strings = type.split(":");
                        String otherName = strings[1];
                        recvs = new ArrayList<>();
                        recvs.add(socketMap.get(otherName));
                    }
                    // 接收消息
                    String msg = dataInputStream.readUTF();
                    for (Socket recv : recvs) {
                        // 转发给接收者
                        DataOutputStream dataOutputStream =
                                new DataOutputStream(recv.getOutputStream());
                        dataOutputStream.writeUTF("msg");
                        dataOutputStream.writeUTF(name + "说:" + msg);
                    }
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}
